package com.myy.auth.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.myy.auth.config.LoginConfig;
import com.myy.auth.constants.CommonConstants;
import com.myy.auth.entity.User;
import com.myy.auth.mapper.UserMapper;
import com.myy.auth.vo.LoginUser;
import com.myy.auth.vo.PasswordVo;
import com.myy.auth.vo.SessionUser;
import com.myy.common.exception.ParamException;
import com.myy.common.utils.PwdUtil;
import lombok.AllArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
* @author ADMIN
* @description 针对表【sys_user(用户表)】的数据库操作Service
* @createDate 2025-08-16 23:41:12
*/
@AllArgsConstructor
@Service
public class UserService extends ServiceImpl<UserMapper, User> {

    private final LoginConfig loginConfig;
    private final RedisTemplate redisTemplate;

    /**
     * 用户登录
     */
    public SessionUser login(LoginUser loginUser) {
        if (loginUser == null) {
            throw new ParamException("参数不能为空");
        }
        User user = baseMapper.selectOne(new LambdaQueryWrapper<User>()  //注册控制，用户名唯一性
                .eq(User::getUsername, loginUser.getUsername())
        );
        if (user == null) {
            throw new ParamException("账号或密码错误，请重新输入");
        }
        if (StrUtil.isBlank(user.getPassword())) {
            throw new ParamException("用户数据密码为空，请联系管理员");
        }
        if (!CommonConstants.COM_YES.equals(user.getStatus())) {
            throw new ParamException("账号已被禁用，请联系管理员");
        }
        Integer loginErrorCount = null;
        if (loginConfig.isLock()) {//登录错误5次锁定10分钟
            loginErrorCount = (Integer) redisTemplate.opsForValue().get("login_error_count:" + user.getId());
            if (loginErrorCount != null && loginErrorCount >= 5) {
                throw new ParamException("错误次数太多，10分钟后再试");
            }
        }
        if (!PwdUtil.verify(loginUser.getPassword(), user.getPassword())) {
            if (loginConfig.isLock()) {
                redisTemplate.opsForValue().set("login_error_count:" + user.getId(), loginErrorCount == null ? 1 : loginErrorCount + 1, 10, TimeUnit.MINUTES);
            }
            throw new ParamException("账号或密码错误，请重新输入");
        } else {
            if (loginConfig.isLock()) { //清理错误次数
                redisTemplate.delete("login_error_count:" + user.getId());
            }
        }
        SessionUser sessionUser = BeanUtil.toBean(user, SessionUser.class);
        String token = UUID.randomUUID().toString();
        sessionUser.setToken(token);
        sessionUser.setCreationTime(LocalDateTime.now());
        if (loginConfig.isOnly()) {//同一个用户只能在一个浏览器中登录
            String oldToken = (String) redisTemplate.opsForValue().get("login_only" + user.getId());
            if (StrUtil.isNotBlank(oldToken)) {
                redisTemplate.delete(oldToken);
            }
            redisTemplate.opsForValue().set("login_only" + user.getId(), token);
        }
        redisTemplate.opsForValue().set(sessionUser.getToken(), JSONUtil.toJsonStr(sessionUser), 2, TimeUnit.HOURS);  //已缓存，退出登录
        if (!PwdUtil.verifyPassword(loginUser.getPassword())) {
            sessionUser.setPasswordChange(true);
            sessionUser.setPasswordMessage("密码格式太简单");
        }
//        else if (PwdUtil.passwordExpire(user.getPasswordDate())) {
//            sessionUser.setPasswordChange(true);
//            sessionUser.setPasswordMessage("3个月未修改密码");
//        }
        return sessionUser;
    }

    /**
     * 退出登录
     * @param token
     * @return
     */
    public String logout(String token) {
        if(StrUtil.isBlank(token)) {
            throw new ParamException("参数不能为空");
        }
        if(Boolean.TRUE.equals(redisTemplate.hasKey(token))) {
            redisTemplate.delete(token);
        }
        //ToDo 清除当前人全部缓存信息
        return "退出成功";
    }

    /**
     * 修改密码
     * @param vo
     * @return
     */
    public String changePwd(PasswordVo vo) {
        if(vo == null) {
            throw new ParamException("参数不能为空");
        }
        if(StrUtil.isBlank(vo.getOldPassword()) || StrUtil.isBlank(vo.getNewPassword())) {
            throw new ParamException("参数不能为空");
        }
        //SysUser user = baseMapper.selectById(UserUtil.getUserId());//ToDo userId放到header中
        User user = baseMapper.selectById(vo.getUserId());
        if (user == null) {
            throw new ParamException("用户不存在");
        }
        if (!PwdUtil.verify(vo.getOldPassword(), user.getPassword())) {
            throw new ParamException("原密码错误");
        }
        baseMapper.update(new LambdaUpdateWrapper<User>().
                set(User::getPassword, PwdUtil.password(vo.getNewPassword()))
                .eq(User::getId, user.getId()));
        return "修改成功";
    }
//    //生成用户
//    public String create(SysUserVo userVo) {
//    }

}
